//
//  vdAction.h
//  Void Dead
//
//  Created by Sidney Just on 19.03.10.
//  Copyright © 2009 by Sidney Just
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
//  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
//  and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
//  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
//  FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
//  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#import <Foundation/Foundation.h>

/**
 * A vdAction can be used to repeat different actions over the whole lifetime of a node.
 * A vdAction itself does nothing more than invoking a function which will execute the action (or something else). Actions can be assigned to vdNodes.
 **/
typedef struct {
	/**
	 * The instance of the class that contains the action function
	 **/
	id target;
	/**
	 * The selector of the action
	 **/
	SEL selector;
	
	/**
	 * The C function with the action
	 **/
	void (*callback)(id);
	
	/**
	 * If this is set to YES the vdAction will invoke the id with the selector, otherwise the callback function will be called.
	 **/
	BOOL objcClass;
	
	/**
	 * A pointer which can hold user defined data
	 @remark The target or callback (depends on objcClass) will be notified when it's time to free the data 
	 (the sender field will be NULL, you can get the pointer to action that will be deleted by calling vdGetCurrentAction())
	 **/
	void *data;
	
	/**
	 * The retain count of the action.
	 **/
	int retainCount;
} vdAction;


#ifdef __cplusplus
extern "C" {
#endif
	
	/**
	 * \defgroup Action Action
	 */
	/*@{*/

	/**
	 * This will create a new action which will invoke the given target and selector (the selector will receive the id of the sender)
	 @param target Class instance
	 @param selector The selector that should be notified
	 @return Pointer to a new action. Can be assigned to any vdNode.
	 **/
	vdAction *vdCreateAction(id target, SEL selector);
	
	/**
	 * This will create a new action which will invoke the given function (the function will receive the id of the sender)
	 @param target Pointer to the C function
	 @return Pointer to a new action. Can be assigned to any vdNode.
	 **/
	vdAction *vdCreateCAction(void (*target)(id));
		
	/**
	 * Returns the pointer to the action that will be deleted (if no action will be deleted, the function returns NULL). Your target/callback will be notified with NULL as sender when a action
	 will be deleted.
	 @return Pointer to the action that will be deleted.
	 **/
	vdAction *vdGetCurrentAction();
		
	/**
	 * Deletes the given action and calls also the target/callback with NULL as sender so you can free all allocated memory for the data pointer (you can use vdGetCurrentAction() to get a Pointer
	 to the vdAction that will be deleted)
	 @param action The action you want to delete
	 @remark The action will be only deleted if the retain count is <= 0 (the function will subtract 1 from the retain count).
	 **/
	void vdDeleteAction(vdAction *action);
		
	/*@}*/
	
#ifdef __cplusplus
}
#endif